package com.leyou.auth.service;

import com.leyou.auth.client.GoodsClient;
import com.leyou.auth.interceptor.LoginInterceptor;
import com.leyou.auth.mapper.CollectionsMapper;
import com.leyou.auth.pojo.Cart;
import com.leyou.auth.pojo.Collections;
import com.leyou.auth.pojo.UserInfo;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.pojo.Sku;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @Author: taft
 * @Date: 2018-10-27 12:08
 */
@Service
public class CartService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private GoodsClient goodsClient;

    @Autowired
    private CollectionsMapper collectionsMapper;

    private String KEY_PREFIX = "ly:cart:uid:";

    public void addCart(Cart cart) {
        BoundHashOperations<String, Object, Object> ops = this.getCarts();
        if (ops == null) {
            return;
        }
        cart.setUserId(this.getUserId());
        //获取单个商品信息
        Object obj = ops.get(cart.getSkuId().toString());
        if (obj == null) {
            //为空,将传递过来的cart对象直接设置到Redis当中
            ops.put(cart.getSkuId().toString(), JsonUtils.serialize(cart));
        } else {
            //将商品信息的Json格式转换为对象
            Cart storeCart = JsonUtils.parse(obj.toString(), Cart.class);
            //不为空,修改数量即可
            storeCart.setNum(storeCart.getNum() + cart.getNum());
            //再设置到Redis中
            ops.put(storeCart.getSkuId().toString(), JsonUtils.serialize(storeCart));
        }
    }

    public Map<String, Object> queryCarts(Cart[] localCarts) {
        //结果集
        Map<String, Object> resultMap = new HashMap<>();
        //购物车商品集合
        List<Cart> carts = new ArrayList<>();
        //差价price集合
        List<Map<Long, Long>> diffPrice = new ArrayList<>();
        //失效商品集合
        List<Long> invalid = new ArrayList<>();
        //查询购物车商品信息
        BoundHashOperations<String, Object, Object> ops = this.getCarts();
        if (ops == null) {
            return null;
        }
        //判断本地LocalStorage中是否有存储
        if (localCarts == null || localCarts.length == 0) { //本地没有存储,直接查Redis数据即可
            //获取购物车信息
            List<Object> userCarts = ops.values();
            //判空校验
            if (CollectionUtils.isEmpty(userCarts)) {
                return null;
            }
            //循环添加购物车商品到集合
            for (Object value : userCarts) {
                Cart cart = JsonUtils.parse(value.toString(), Cart.class);
                carts.add(cart);
            }
        } else { //本地有数据,将本地购物车信息存储到Redis当中
            //先将本地购物车信息,合并到Redis中
            for (Cart localCart : localCarts) {
                localCart.setUserId(this.getUserId()); //为每个对象设置UserId
                ops.put(localCart.getSkuId().toString(), JsonUtils.serialize(localCart)); //设置到Redis当中
            }
            //再进行查询
            List<Object> userCarts = ops.values();
            //购物车为空,直接return
            if (CollectionUtils.isEmpty(userCarts)) {
                return null;
            }
            for (Object value : userCarts) {
                carts.add(JsonUtils.parse(value.toString(), Cart.class));
            }
        }

        //校验上下架,差价信息
        for (Cart cart : carts) {
            //购物车中的商品实际对应的商品
            Sku sku = this.goodsClient.querySkuById(cart.getSkuId());
            //失效商品
            if (!sku.getEnable()) {
                invalid.add(sku.getId());
            }
            long cartPrice = cart.getPrice();
            long skuPrice = sku.getPrice();
            Map<Long, Long> diffMap = new HashMap<>();
            //价格不等
            if (sku.getEnable() && skuPrice != cartPrice) {
                diffMap.put(cart.getSkuId(), skuPrice - cartPrice);
                diffPrice.add(diffMap);
            }
            //更新价格不等的商品,但Redis中数据不变
            Set<Long> keySet = diffMap.keySet();
            for (Long diffId : keySet) {
                for (Cart diffCart : carts) {
                    if (diffCart.getSkuId() == diffId) {
                        Long diffPrice2 = diffMap.get(diffId);
                        diffCart.setPrice(diffCart.getPrice() + diffPrice2);
                    }
                }
            }
            resultMap.put("carts", carts);
            resultMap.put("diffPrice", diffPrice);
            resultMap.put("invalid", invalid);
        }
        return resultMap;
    }

    @Transactional
    public void updateCarts(Cart cart) {
        BoundHashOperations<String, Object, Object> ops = this.getCarts();
        if (ops == null) {
            return;
        }
        cart.setUserId(this.getUserId());
        //根据当前商品的skuId查询商品
        Cart c = JsonUtils.parse(ops.get(cart.getSkuId().toString()).toString(), Cart.class);
        c.setNum(cart.getNum());
        //写入购物车
        ops.put(cart.getSkuId().toString(), JsonUtils.serialize(c));
    }

    public void deleteCarts(Long id) {
        BoundHashOperations<String, Object, Object> ops = this.getCarts();
        if (ops == null) {
            return;
        }
        if (id != null) {
            ops.delete(id.toString());
        }
    }

    public Integer queryCartsLength(Integer cartsLength) {
        BoundHashOperations<String, Object, Object> ops = this.getCarts();
        if (ops == null) {
            return null;
        }
        List<Object> values = ops.values();
        return values.size() + cartsLength;
    }


    //获取用户的购物车信息
    public BoundHashOperations<String, Object, Object> getCarts() {
        //查询用户
        UserInfo userInfo = LoginInterceptor.getUserInfo();
        //校验用户
        if (userInfo == null) {
            return null;
        }
        //查询Carts信息
        return redisTemplate.boundHashOps(KEY_PREFIX + userInfo.getId());
    }

    //获取用户ID
    public Long getUserId() {
        return LoginInterceptor.getUserInfo().getId();
    }

    @Transactional
    public Boolean addMyFavorite(Long id) {
        //查询sku信息
        Sku sku = this.goodsClient.querySkuById(id);
        Collections collections = new Collections();
        collections.setSkuId(sku.getId());
        collections.setUserId(this.getUserId());
        collections.setImage(sku.getImages());
        collections.setOwnSpec(sku.getOwnSpec());
        collections.setTitle(sku.getTitle());
        collections.setPrice(sku.getPrice());
        collections.setSpuId(sku.getSpuId());
        collections.setNum(1);
        //添加到collections表中
        int result = this.collectionsMapper.insertSelective(collections);
        if (result == 0) {
            return false;
        }
        return true;
    }

    @Transactional
    public void moveSelected(Cart[] carts) {
        List<Sku> skuList = new ArrayList<>();
        for (Cart cart : carts) {
            Sku sku = this.goodsClient.querySkuById(cart.getSkuId());
            skuList.add(sku);
        }
        for (Sku sku : skuList) {
            Collections collections = new Collections();
            collections.setSkuId(sku.getId());
            collections.setUserId(this.getUserId());
            collections.setImage(sku.getImages());
            collections.setOwnSpec(sku.getOwnSpec());
            collections.setTitle(sku.getTitle());
            collections.setPrice(sku.getPrice());
            collections.setSpuId(sku.getSpuId());
            collections.setNum(1);
            this.collectionsMapper.insertSelective(collections);
        }
    }


    public List<Collections> queryMyFavorite() {
        Collections collections = new Collections();
        collections.setUserId(LoginInterceptor.getUserInfo().getId());
        List<Collections> list = this.collectionsMapper.select(collections);
        return list;
    }

    @Transactional
    public void removeSelectedCarts(Cart[] carts) {
        BoundHashOperations<String, Object, Object> ops = this.getCarts();
        if (ops == null) {
            return;
        }
        for (Cart cart : carts) {
            ops.delete(cart.getSkuId() + "");
        }
    }

    public void clearOut(String[] invalids) {
        BoundHashOperations<String, Object, Object> ops = this.getCarts();
        if (ops == null) {
            return;
        }
        for (String invalid : invalids) {
            ops.delete(invalid);
        }
    }

    public Boolean removeFavorite(Long id) {
        Collections collections = new Collections();
        //获取用户id
        Long userId = this.getUserId();
        //未登录直接返回fasle
        if (userId == null) {
            return false;
        }
        collections.setUserId(userId);
        collections.setSkuId(id);
        int delete = this.collectionsMapper.delete(collections);
        return delete > 0;
    }

    public Boolean removeAllFavorite() {
        Collections collections = new Collections();
        //获取用户id
        Long userId = this.getUserId();
        //未登录直接返回fasle
        if (userId == null) {
            return false;
        }
        collections.setUserId(userId);
        int delete = this.collectionsMapper.delete(collections);
        return delete > 0;
    }

    public Boolean addDeleteToFavorite(Collections collection) {
        Sku sku = this.goodsClient.querySkuById(collection.getSkuId());
        collection.setSpuId(sku.getSpuId());
        collection.setUserId(LoginInterceptor.getUserInfo().getId());
        return this.collectionsMapper.insertSelective(collection) > 0;
    }

    public void clearSettleCarts(List<Long> ids) {
        //获取用户id
        Long userId = this.getUserId();
        //未登录直接返回
        if (userId == null) {
            return;
        }
        BoundHashOperations<String, Object, Object> carts = this.getCarts();
        //遍历删除对应的商品
        for (Long id : ids) {
            carts.delete(id + "");
        }
    }
}
